package com.techysky.service.impl;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.techysky.config.IetmConfig;
import com.techysky.entity.CommentTags;
import com.techysky.entity.DataModule;
import com.techysky.repository.CommentTagsRepository;
import com.techysky.repository.DataModuleRepository;
import com.techysky.service.CommentTagsService;
import com.techysky.util.CoreUtils;
import com.techysky.util.IetmFileUtils;

@Service("commentTagsService")
public class CommentTagsServiceImpl implements CommentTagsService {
	private static final String SUCCESS = "success";
	private static final String VISIBILITY = "visibility";
	private static final String FILE = "/file/";
	private static final String COMMENT = "comment";
	private static final Log log=LogFactory.getLog(CommentTagsServiceImpl.class);	
	@Autowired
	private CommentTagsRepository commentTagsRepository;
	@Autowired
	private DataModuleRepository dataModuleRepository;
	@Autowired
	private IetmConfig ietmConfig;

	@Override
	public Object saveOrUpdate(CommentTags commentTags) {
		DataModule dataModule=dataModuleRepository.findByDmCode(commentTags.getCode());
		if(null!=commentTags.getType()&&COMMENT.equals(commentTags.getType())) {
			extract1(commentTags);
		}
		commentTags.setDmodelId(dataModule.getId());
		return this.commentTagsRepository.save(commentTags);
	}

	private void extract1(CommentTags commentTags) {
		if(commentTags.getFile()!=null&&!"".equals(commentTags.getFile())) {
			try {
				IetmFileUtils.commentZip(commentTags.getFile(), ietmConfig.getFilePath());
			} catch (Exception e) {
				log.info(e);
			}
			commentTags.setFile(FILE+commentTags.getFile().substring(commentTags.getFile().lastIndexOf('\\')+1));
		}
	}

	@Override
	public Map<String, Object> query(CommentTags commentTags) {
		Map<String,Object> result=new HashMap<>();
		 if("commentv".equals(commentTags.getOperation())) {
			 commentTags.setType(COMMENT);
			 result.put("rows", CoreUtils.getInstance().convert(this.commentTagsRepository.findAll(queryConditions(commentTags))));
		}else {
			commentTags.setPage(commentTags.getPage()!=null?commentTags.getPage():0);
			commentTags.setSize(commentTags.getSize()!=null?commentTags.getSize():8);
			if(COMMENT.equals(commentTags.getOperation())) {
				commentTags.setType(COMMENT);
			}else if("tag".equals(commentTags.getOperation())) {
				commentTags.setType("tag");
			}
			Page<CommentTags> resultList=this.commentTagsRepository.findAll(queryConditions(commentTags),new PageRequest(commentTags.getPage(),commentTags.getSize()));
			result.put("page", commentTags.getPage()+1);
			result.put("size", commentTags.getSize());
			result.put("search", commentTags.getContent()!=null?commentTags.getContent():(commentTags.getTitle()!=null?commentTags.getTitle():""));
			result.put("rows", CoreUtils.getInstance().convert(resultList.getContent()));
			result.put("total", resultList.getTotalElements());
		}
		return result;
	}	/**
	 * 等值匹配条件
	 * @return
	 */
	public Specification<CommentTags> queryConditions(final CommentTags commentTags){
		return (Root<CommentTags> root,CriteriaQuery<?> query, CriteriaBuilder cb)->{
			List<Predicate> predicate = new ArrayList<>();
			if(commentTags!=null) {
				if(null!=commentTags.getCode()){
					predicate.add(cb.equal(root.get("projectId"),commentTags.getProjectId()));
				}
					predicate.add(cb.equal(root.get("type"),commentTags.getType()));
					queryConExtract(commentTags, root, cb, predicate);
					}
			Predicate[] pre = new Predicate[predicate.size()];
			query.orderBy(cb.asc(root.get("orderCode")));
			return query.where(predicate.toArray(pre)).getRestriction();};
	}

	public void queryConExtract(final CommentTags commentTags, Root<CommentTags> root, CriteriaBuilder cb,
			List<Predicate> predicate) {
		if(commentTags.getCode()!=null)
			predicate.add(cb.equal(root.get("code"),commentTags.getCode()));
		if(commentTags.getDmodelId()!=null)
			predicate.add(cb.equal(root.get("dmodelId"),commentTags.getDmodelId()));
		if(commentTags.getContent()!=null&&!"".equals(commentTags.getContent()))
			predicate.add(cb.like(root.get("content"),"%"+commentTags.getContent()+"%"));
		if(commentTags.getTitle()!=null&&!"".equals(commentTags.getTitle()))
			predicate.add(cb.like(root.get("title"),"%"+commentTags.getTitle()+"%"));
		if(commentTags.getUserName()!=null) {
			Predicate p = cb.and(cb.equal(root.get(VISIBILITY), "1"), cb.equal(root.get("userName"), commentTags.getUserName())); 
			p=cb.or(cb.equal(root.get(VISIBILITY) , "0"), p);  
			predicate.add(p);}
	}

	@Override
	public Object delete(String ids) {
		for (String id : ids.split(",")) {
			this.commentTagsRepository.delete(this.commentTagsRepository.findOne(id));
		}
		return SUCCESS;
	}

	@Override
	public Map<String, Object> getObject(String id) {
		Map<String,Object> result=new HashMap<>();
		result.put("commentTags", CoreUtils.getInstance().entity2Map(this.commentTagsRepository.findOne(id)));
		return result;
	}

	@Override
	public Object uploadFile(MultipartFile file) {
		String fileName = file.getOriginalFilename();          
		        
		File target = new File(ietmConfig.getFilePath(), fileName);          
		if(!target.exists())
		{target.mkdirs();}          
		//保存         
		try { 
			extract3(file, target);
			} 
		catch (Exception e) {
			log.info(e);
			}  		
		return SUCCESS;	
	}

	@Override
	public Object uploadFile(HttpServletRequest request) {
		 MultipartHttpServletRequest params=(MultipartHttpServletRequest) request;    
         List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("file");     
         String id=params.getParameter("id");
         CommentTags commentTags=this.commentTagsRepository.findOne(id);
        
         files.forEach(file->{
        	 String fileName = file.getOriginalFilename();  
        	 commentTags.setFile(FILE+fileName.substring(fileName.lastIndexOf('\\')+1));
        	 this.commentTagsRepository.save(commentTags);
     		 File target = new File(ietmConfig.getFilePath(),fileName.substring(fileName.lastIndexOf('\\')+1)); 
     		//保存         
     		 try { 
     			 extract3(file, target);
     			 } catch (Exception e) 
     		 {log.info(e);}  	 
         });
 		 return "上传成功";	
	}

	@Override
	public Object deleteFile(String id) {
		CommentTags commentTags=this.commentTagsRepository.findOne(id);
		commentTags.setFile(null);
		this.commentTagsRepository.save(commentTags);
		return SUCCESS;
	}

	@Override
	public List<CommentTags> findByProject(String projectId) {
		CommentTags commentTags=new CommentTags();
		commentTags.setType(COMMENT);
		return this.commentTagsRepository.findAll(queryConditions(commentTags));
	}

	/**
	 * 
	 * @描述:
	 * @方法名: saveOrUpdate
	 * @param request
	 * @return
	 * @创建人：lin
	 * @创建时间：2018年10月16日下午5:08:41
	 * @修改人：lin
	 * @修改时间：2018年10月16日下午5:08:41
	 * @修改备注：页面字段名称与方法名称保持一致219行
	 * @throws
	 */
	@Override
	public Object saveOrUpdate(HttpServletRequest request) {
		 List<MultipartFile> files=null;
         String id=request.getParameter("id");
         String code=request.getParameter("code");
         String posX=request.getParameter("posX");
         String posY=request.getParameter("posY");
         String version=request.getParameter("version");
         String publishDate=request.getParameter("publishDate");
         String userName=request.getParameter("userName");
         String visibility=request.getParameter(VISIBILITY);
         String title=request.getParameter("title");
         String type=request.getParameter("type");
         String content=request.getParameter("content");
         String dmodelId =request.getParameter("dmodelId");
         String projectId =request.getParameter("projectId");
         if(COMMENT.equals(type)) {
             files = ((MultipartHttpServletRequest) request).getFiles("file"); 
         }
         CommentTags commentTags;
         if(id!=null){
        	 commentTags=this.commentTagsRepository.findOne(id);
        	 if(COMMENT.equals(type)) {
        		 commentTags.setVersion(version);
            	 commentTags.setPublishDate(publishDate);
            	 commentTags.setUserName(userName);
            	 commentTags.setTitle(title);
            	 commentTags.setContent(content);
            	 commentTags.setDmodelId(dmodelId);
            	 commentTags.setVisibility(visibility);
            	 commentTags.setProjectId(projectId);
        	 }else {
        		 commentTags.setTitle(title);
        		 commentTags.setContent(content);
        		 commentTags.setDmodelId(dmodelId);
        		 commentTags.setUserName(userName);
        		 commentTags.setProjectId(projectId);
        	 }
        	 
         }else {
        	 commentTags=new CommentTags();
        	 commentTags.setCode(code);
        	 if(COMMENT.equals(type)) {
        		 commentTags.setPosX(Double.valueOf(posX));
            	 commentTags.setPosY(Double.valueOf(posY));
            	 commentTags.setVersion(version);
            	 commentTags.setUserName(userName);
            	 commentTags.setType(type);
            	 commentTags.setPublishDate(publishDate); 
            	 commentTags.setTitle(title);
            	 commentTags.setContent(content);
            	 commentTags.setDmodelId(dmodelId);
            	 commentTags.setVisibility(visibility);
            	 commentTags.setProjectId(projectId);
        	 }else {
        		 if("p".equals(type)){
        			 SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        			 commentTags.setPublishDate(sdf.format(Calendar.getInstance().getTime()));
        		 }
        		 commentTags.setTitle(title);
        		 commentTags.setType(type);
        		 commentTags.setContent(content);
        		 commentTags.setDmodelId(dmodelId);
        		 commentTags.setUserName(userName);
        		 commentTags.setProjectId(projectId);
        	 }
         }
         extract2(files, commentTags);
         CommentTags tags=this.commentTagsRepository.save(commentTags);
 		 return tags.getId();	
	}

	private void extract2(List<MultipartFile> files, CommentTags commentTags) {
		if(files!=null&&!files.isEmpty()) {
        	 for (MultipartFile file : files) {
        		 extract3(commentTags, file);
    		} 
         }
	}

	private void extract3(CommentTags commentTags, MultipartFile file) {
		if(file.getOriginalFilename()!=null&&!"".equals(file.getOriginalFilename())) {
			 String fileName = file.getOriginalFilename();  
		 	 commentTags.setFile(FILE+fileName.substring(fileName.lastIndexOf('\\')+1));
		 	
			 File target = new File(ietmConfig.getFilePath(),fileName.substring(fileName.lastIndexOf('\\')+1)); 
			//保存         
			 try {
				 extract3(file, target);
				 } catch (Exception e) {
					 log.info(e);
					 }  	
		 }
	}

	private void extract3(MultipartFile file, File target) throws IOException {
		file.transferTo(target);
	}

	@Override
	public Object updateAnnoById(CommentTags commentTags) {
		
		CommentTags com = commentTagsRepository.findOne(commentTags.getId());
		com.setContent(commentTags.getContent());
		commentTagsRepository.save(com);
		return SUCCESS;
	}

}
